# -*- coding:utf-8 -*-

from typing import Union
import pymysql
import json


def dict_list2ddict(dlist: list, parse_col_name: str) -> dict:
    """数据库查询返回的字典列表，转化为以指定列(一般为主键)的值为键的字典"""
    ddict = {}
    for d in dlist:
        ddict[d[parse_col_name]] = d
    return ddict


def get_tree_node_path_by_dlist(nodes_dlist: [list, dict], parse_col_kv: tuple, parent_key: str or int, ret_key: str) -> list:
    """根据从数据库查出的全部节点信息，以列表形式返回指定节点的树形节点路径"""
    def recurrence_by_parent_key(ddict: dict, looking_for_key):
        if not ddict[looking_for_key][parent_key]:
            return [ddict[looking_for_key][ret_key]]
        else:

            return [ddict[looking_for_key][ret_key]] + recurrence_by_parent_key(ddict, ddict[looking_for_key][parent_key])

    looking_for_k, looking_for_v = parse_col_kv
    if isinstance(nodes_dlist, list):
        ddict = dict_list2ddict(dlist=nodes_dlist, parse_col_name=looking_for_k)
    else:
        ddict = nodes_dlist
    ret_list = recurrence_by_parent_key(ddict=ddict, looking_for_key=looking_for_v)
    ret_list.reverse()
    return ret_list


def get_tree_child_nodes_by_dlist(nodes_dlist: list, dlist_prase_key, parent_name, parent_value) -> list:
    """根据从数据库查出的全部节点信息，以列表形式返回指定节点的所有子节点"""
    def get_children(parent_values, ddict: dict):
        node_id = []
        for k, v in ddict.items():
            if v[parent_name] in parent_values:
                node_id.append(k)
        return node_id

    ddict = dict_list2ddict(dlist=nodes_dlist, parse_col_name=dlist_prase_key)
    nodes = []
    childen = get_children([parent_value], ddict)
    nodes += childen
    while True:
        childen = get_children(childen, ddict)
        if not childen:
            break
        nodes += childen
    return nodes


def get_dlist_key_values(dlist: list, key: str or list, where: dict={}, where_not: dict={}) -> list:
    values = []
    for d in dlist:
        if_append = True
        for k, v in where_not.items():
            if d[k] == v:
                if_append = False
                break
        if if_append:
            for k, v in where.items():
                if d[k] != v:
                    if_append = False
                    break
        if if_append:
            if isinstance(key, list):
                keys_value_list = []
                for key_i in key:
                    keys_value_list.append(d[key_i])
                values.append(keys_value_list)
            else:
                values.append(d[key])
    return values


def data2sql_in(data: Union[str, tuple, list, type({}.keys())]):
    s = str(tuple(data))
    if len(data) == 1:
        s = s.replace(',', '')
    elif len(data) == 0:
        s = ''
    return s


def str2db_null(s: str or int):
    if isinstance(s, str):
        if not s:
            return None
        else:
            return s
    else:
        return s


def escape_string(data: str):
    pymysql.escape_string(data)


def dict2db_json(data: dict) -> str:
    lis = []
    for k, v in data.items():
        lis.append(k)
        lis.append(str(v))
    s = json.dumps(lis, ensure_ascii=False)[1:-1]
    return s


def get_tree_parent_nodes_by_dlist(
        nodes_dlist: list=None, nodes_ddict: dict=None, dlist_prase_key=None, parent_name=None, child_id=None
) -> list:
    """根据从数据库查出的全部节点信息，以列表形式返回指定节点的所有子节点"""
    def get_parent(child, ddict: dict):
        for k, v in ddict.items():
            if v[dlist_prase_key] == ddict[child][parent_name]:
                return k

    if not nodes_ddict:
        ddict = dict_list2ddict(dlist=nodes_dlist, parse_col_name=dlist_prase_key)
    else:
        ddict = nodes_ddict
    parents = []
    while True:
        parent = get_parent(child_id, ddict)
        if not parent:
            break
        parents.append(parent)
        child_id = parent
    return parents


if __name__ == '__main__':

    def merge_frame(ddlist: dict, frame_id):
        el = ddlist[frame_id]
        if not el['frame_id']:
            return el['by'] + '#' + el['value']
        else:
            return el['by'] + '#' + el['value'] + '|' + merge_frame(ddlist, el['frame_id'])


    def merge_frame2(ddlist: dict, frame_id):
        """递归找frame路径"""
        el = ddlist[frame_id]
        if not el['frame_id']:
            return [el]
        else:
            t = merge_frame2(ddlist, el['frame_id'])
            ret = [el] + t
            return ret

    data = [
            {
                'id': 1,
                'name': '11',
                'expr': "xpath#//frame1",
                'by': 'xpath',
                'value': '//frame1',
                'frame_id': ''
            },
            {
                'id': 2,
                'name': '22',
                'expr': "xpath#//frame2",
                'by': 'xpath',
                'value': '//frame2',
                'frame_id': 1
            },
            {
                'id': 5,
                'name': '22',
                'expr': "xpath#//frame2",
                'by': 'xpath',
                'value': '//frame1',
                'frame_id': 1
            },
            {
                'id': 6,
                'name': '22',
                'expr': "xpath#//frame2",
                'by': 'xpath',
                'value': '//frame1',
                'frame_id': 5
            },
            {
                'id': 3,
                'name': '33',
                'expr': "xpath#//frame3",
                'by': 'xpath',
                'value': '//frame1',
                'frame_id': 2
            },
            {
                'id': 4,
                'name': '44',
                'expr': "xpath#//frame4",
                'by': 'xpath',
                'value': '//frame1',
                'frame_id': ''
            },
        ]

    # ddict = dict_list2ddict(data, 'id')

    # print(ddict)

    # dframe = {}
    # for frame_id in ddict.keys():
    #     d = merge_frame2(ddict, frame_id)
    #     d.reverse()
    #     dframe[frame_id] = d
    # print(dframe)
    # print(json.dumps(dframe, ensure_ascii=False, indent=4))

    # print(get_tree_node_path_by_dlist(nodes_dlist=data, parse_col_kv=('id', 3), parent_key='frame_id', ret_key='expr'))

    # n = get_tree_parent_nodes_by_dlist(
    #     nodes_dlist=data,
    #     dlist_prase_key='id',
    #     parent_name='frame_id',
    #     child_id=6
    # )
    # print(n)

    # get_tree_node_path_by_dlist(
    #     nodes_dlist=data,
    #     looking_for_kv=('id', 5),
    #     parent_key='frame_id',
    #     ret_key=('id',)
    # )
